///*
// * Copyright (c) 2001, Zoltan Farkas All Rights Reserved.
// *
// * This library is free software; you can redistribute it and/or
// * modify it under the terms of the GNU Lesser General Public
// * License as published by the Free Software Foundation; either
// * version 2.1 of the License, or (at your option) any later version.
// *
// * This library is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU Lesser General Public
// * License along with this program; if not, write to the Free Software
// * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// */
//package org.spf4j.stackmonitor;
//
//import java.lang.invoke.MethodHandle;
//import java.lang.invoke.MethodHandles;
//import java.lang.reflect.InvocationTargetException;
//import java.security.AccessController;
//import java.security.PrivilegedAction;
//
///**
// * This is a high performance sampling collector.
// * The goal is for the sampling overhead to be minimal.
// * This is better than the SimpleStackCollector in 2 ways:
// * 1) No HashMap is created during sampling. Resulting in less garbage generated by sampling.
// * 2) Stack trace for the sampling Thread is not created at all, saving some time and creating less garbage.
// *
// * in java 1.7 the reflective invocations can probably be further optimized using:
// * http://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandle.html
// * http://stackoverflow.com/questions/14146570/
// * calling-a-getter-in-java-though-reflection-whats-the-fastest-way-to-repeatedly
// * @author zoly
// */
//public final class FastStackCollector7 extends AbstractStackCollector {
//
//    private static final MethodHandle GET_THREADS;
//    private static final MethodHandle DUMP_THREADS;
//
//    static {
//        final java.lang.reflect.Method getThreads;
//        final java.lang.reflect.Method dumpThreads;
//        try {
//
//            getThreads = Thread.class.getDeclaredMethod("getThreads");
//            dumpThreads = Thread.class.getDeclaredMethod("dumpThreads", Thread[].class);
//        } catch (SecurityException ex) {
//            throw new RuntimeException(ex);
//        } catch (NoSuchMethodException ex) {
//            throw new RuntimeException(ex);
//        }
//        AccessController.doPrivileged(new PrivilegedAction() {
//            @Override
//            public Object run() {
//                getThreads.setAccessible(true);
//                dumpThreads.setAccessible(true);
//                return null; // nothing to return
//            }
//        });
//        MethodHandles.Lookup lookup = MethodHandles.lookup();
//        try {
//            GET_THREADS = lookup.unreflect(getThreads);
//            DUMP_THREADS = lookup.unreflect(dumpThreads);
//        } catch (IllegalAccessException ex) {
//            throw new RuntimeException(ex);
//        }
//
//    }
//
//    @Override
//    @edu.umd.cs.findbugs.annotations.SuppressWarnings("EXS_EXCEPTION_SOFTENING_NO_CHECKED")
//    public void sample(final Thread ignore) {
//        try {
//            Thread[] threads = (Thread[]) GET_THREADS.invokeExact();
//            final int nrThreads = threads.length;
//            for (int i = 0; i < nrThreads; i++) {
//                if (ignore == threads[i]) { // not interested in the sampler's stack trace
//                    threads[i] = null;
//                    break;
//                }
//            }
//            StackTraceElement[][] stackDump = (StackTraceElement[][]) DUMP_THREADS.invokeExact(threads);
//            for (StackTraceElement[] stackTrace : stackDump) {
//                if (stackTrace != null && stackTrace.length > 0) {
//                        addSample(stackTrace);
//                }
//            }
//        } catch (IllegalAccessException ex) {
//            throw new RuntimeException(ex);
//        } catch (IllegalArgumentException ex) {
//            throw new RuntimeException(ex);
//        } catch (InvocationTargetException ex) {
//            throw new RuntimeException(ex);
//        } catch (RuntimeException e) {
//          throw e;
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        } catch (Throwable e) {
//            throw new Error(e);
//        }
//    }
//
//}
